package top.hmtools.callBacks;

import java.net.URL;
import java.util.List;

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import javafx.util.Callback;
import top.hmtools.base.StringTools;
import top.hmtools.base.ThreadLocalTools;
import top.hmtools.beans.DBConnectInfoBean;
import top.hmtools.beans.tableInfoBeans.TableBaseInfoBean;
import top.hmtools.controllers.AddNewDBConnectionController;
import top.hmtools.enums.EDBType;
import top.hmtools.model.ResultModel;
import top.hmtools.services.DbManageService;

public class SqlConnectionListCallBack implements Callback<TreeView<String>, TreeCell<String>> {
	
	private Callback<TreeView<String>, TreeCell<String>> defaultCellFactory;
	private TreeView<String> treeView; 
	private DbManageService dbManageService;
	private DBConnectInfoBean dbConn;

	public SqlConnectionListCallBack(Callback<TreeView<String>, TreeCell<String>> defaultCellFactory,
			TreeView<String> treeView, DbManageService dbManageService) {
		this.defaultCellFactory = defaultCellFactory;
		this.treeView = treeView;
		this.dbManageService = dbManageService;
	}

	@Override
	public TreeCell<String> call(TreeView<String> tv) {
		TreeCell<String> cell = defaultCellFactory.call(tv);
		cell.addEventHandler(MouseEvent.MOUSE_CLICKED	, new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				int itemLevel = treeView.getTreeItemLevel(cell.getTreeItem());
				TreeCell<String> cellOfSource = (TreeCell<String>) event.getSource();
				TreeItem<String> treeItemOfSource = cellOfSource.getTreeItem();
				
				//给第一层级（数据库链接列表）的数据设置鼠标右键菜单
				if(itemLevel == 1){
					final ContextMenu contextMenu = new ContextMenu();
					MenuItem itemClose = new MenuItem("关闭连接");
					itemClose.setOnAction(event1 -> treeItemOfSource.getChildren().clear());
					
					MenuItem itemDelete = new MenuItem("删除连接");
                    itemDelete.setOnAction(event1 -> {
                    	DBConnectInfoBean dbConn = (DBConnectInfoBean) treeItemOfSource.getGraphic().getUserData();
                    	ResultModel<String> deleteResult =  dbManageService.deleteOneByID(dbConn.getId());
                    	if(deleteResult.isStatusSuccess()){
                    		reLoadData(dbConn.getDb_type());
                    	}
                    });
                    
                    MenuItem itemAddNew = new MenuItem("新增连接");
                    itemAddNew.setOnAction(eventa -> {
                    	URL url = Thread.currentThread().getContextClassLoader().getResource("viewFxml/AddNewDBConnection.fxml");
                		FXMLLoader fxmlLoader = new FXMLLoader(url);
                		
                		Parent root = null;
						try {
							root = fxmlLoader.load();
						} catch (Exception e) {
							e.printStackTrace();
						}
                		Scene scene = new Scene(root);
                		
                		Stage stage = new Stage();
                		stage.setResizable(true);
                		stage.setScene(scene);
                		stage.setTitle("新增数据库链接");
                		stage.show();
                    });
                    
                    MenuItem itemAddEdit = new MenuItem("编辑连接");
                    itemAddEdit.setOnAction(eventa -> {
                    	DBConnectInfoBean dbConn = (DBConnectInfoBean) treeItemOfSource.getGraphic().getUserData();
                    	URL url = Thread.currentThread().getContextClassLoader().getResource("viewFxml/AddNewDBConnection.fxml");
                    	FXMLLoader fxmlLoader = new FXMLLoader(url);
                    	
                    	Parent root = null;
                    	try {
                    		root = fxmlLoader.load();
                    		AddNewDBConnectionController controller = fxmlLoader.getController();
                    		controller.setDBConnection(dbConn);
                    	} catch (Exception e) {
                    		e.printStackTrace();
                    	}
                    	Scene scene = new Scene(root);
                    	
                    	Stage stage = new Stage();
                    	stage.setResizable(true);
                    	stage.setScene(scene);
                    	stage.setTitle("编辑数据库链接");
                    	stage.show();
                    });
                    
                    
                    
                    MenuItem itemRefresh = new MenuItem("刷新连接");
                    itemRefresh.setOnAction(eventaa -> {
                    	DBConnectInfoBean dbConn = (DBConnectInfoBean) treeItemOfSource.getGraphic().getUserData();
                    	reLoadData(dbConn.getDb_type());
                    });
                    contextMenu.getItems().addAll(itemAddNew,itemAddEdit,itemRefresh,itemClose,itemDelete);
                    cell.setContextMenu(contextMenu);
				}
				
				//双击节点事件响应
				int clickCount = event.getClickCount();
				if(clickCount == 2){
					///控制折叠
					if(treeItemOfSource==null){
						return;
					}
					boolean isExpanded = treeItemOfSource.expandedProperty().get();
					treeItemOfSource.setExpanded(isExpanded);
					
					if(itemLevel == 1){
						dbConn = (DBConnectInfoBean) treeItemOfSource.getGraphic().getUserData();
						//添加表信息节点
						ResultModel< TableBaseInfoBean> tables =  dbManageService.getTables(dbConn);
						if(tables.isStatusSuccess()){
							List<TableBaseInfoBean> rows = tables.getRows();
							ObservableList<TreeItem<String>> children = cell.getTreeItem().getChildren();
							children.clear();
							for(TableBaseInfoBean bean:rows){
								TreeItem<String> newTreeItem = new TreeItem<>();
                                ImageView imageView = new ImageView("images/table.png");
                                imageView.setFitHeight(16);
                                imageView.setFitWidth(16);
                                imageView.setUserData(bean);
                                newTreeItem.setGraphic(imageView);
                                newTreeItem.setValue(bean.getTableName());
                                
                                children.add(newTreeItem);
							}
						}
						
					}else if(itemLevel == 2){
						TableBaseInfoBean tableBaseInfoBean = (TableBaseInfoBean) treeItemOfSource.getGraphic().getUserData();
//						dbManageService.getColumns(dbConn,tableBaseInfoBean.getTableName());
						String tableName = tableBaseInfoBean.getTableName();
						setDatas(tableName);
						ThreadLocalTools.get("cb_isCamelVar", CheckBox.class).selectedProperty().addListener(new ChangeListener<Boolean>() {

							@Override
							public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
									Boolean newValue) {
								setDatas(tableName);
							}
						});
					}
				}
			}
		});
		return cell;
	}
	
	/**
	 * 设置表单控件数据
	 * @param tableName
	 */
	private void setDatas(String tableName){
//		ThreadLocalTools.get("cb_isPojoCreatComment", CheckBox.class).selectedProperty().get();
		boolean isCamelVar = ThreadLocalTools.get("cb_isCamelVar", CheckBox.class).selectedProperty().get();
//		ThreadLocalTools.get("cb_isOverrwiterToString", CheckBox.class).setSelected(true);
//		ThreadLocalTools.get("cb_isDaoCreateComment", CheckBox.class).setSelected(true);
		
		String baseName = tableName;
		if(isCamelVar){
			baseName = StringTools.underlineToCamelByRegexAndUpcaseFirstChar(tableName);
		}
		
		ThreadLocalTools.get("tf_tableName", TextField.class).setText(tableName);
		TextField tf_savePath = ThreadLocalTools.get("tf_savePath", TextField.class);
//		tf_savePath.setText("");
		ThreadLocalTools.get("tf_pojoPackage", TextField.class).setText("top.hmtools.pojos");
		ThreadLocalTools.get("tf_pojoName", TextField.class).setText(baseName);
		ThreadLocalTools.get("tf_daoPackage", TextField.class).setText("top.hmtools.daos");

		ThreadLocalTools.get("tf_daoName", TextField.class).setText(baseName+"Dao");
		ThreadLocalTools.get("tf_mapperXmlPackage", TextField.class).setText("top.hmtools.mappers");
		ThreadLocalTools.get("tf_mapperXmlName", TextField.class).setText(baseName+"Mapper.xml");

		ThreadLocalTools.put("dbConnInfo", dbConn);//将数据库连接信息存入threadlocal
		String dbName = EDBType.getByTypeCode(dbConn.getDb_type()).getName();
		ThreadLocalTools.get("cb_dbType", ComboBox.class).setValue(dbName);
//		ThreadLocalTools.get("cb_mapperXmlTemplet", ComboBox.class).setValue("");
//		ThreadLocalTools.get("cb_charset", ComboBox.class).setValue("");
	}
	
	/**
	 * 重新加载数据
	 * @param dbType
	 */
	private void reLoadData(int dbType){
		this.treeView.getRoot().getChildren().clear();
		ResultModel<DBConnectInfoBean> resultModel = this.dbManageService.getConncetionsByDBType(dbType);
        if(resultModel.isStatusSuccess()){
            List<DBConnectInfoBean> rows = resultModel.getRows();
            for(int ii=0;rows != null &&ii<rows.size();ii++){
            	DBConnectInfoBean bean = rows.get(ii);
                TreeItem<String> tItem = new TreeItem<String>();
                tItem.setValue(bean.getName());
                ImageView icon = new ImageView("images/computer.png");
                icon.setFitHeight(16);
                icon.setFitWidth(16);
                icon.setUserData(bean);
                tItem.setGraphic(icon);
                tItem.setGraphic(icon);
                
                this.treeView.getRoot().getChildren().add(tItem);
            }
        }
	}

}
